package com.zb.websocket.server;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 推送进度消息
 * @Author WEN
 * @Date 2023/12/28 0028
 **/
@Component
@ServerEndpoint("/ws/wx/{uuid}")
public class WxWebSocketServer {
    private static final Logger logger = LoggerFactory.getLogger(WxWebSocketServer.class);

    // 在线人数
    private static int onlineCount = 0;

    // 用户存放每个登录的客户端对应的WebSocket对象
    private static ConcurrentHashMap<String, WxWebSocketServer> webSocketMap = new ConcurrentHashMap<>();

    // 与某个登录的客户端的会话连接，需要通过它来给登录的客户端发送数据
    private Session session;

    // 接收进度的uuid唯一识别码
    private String progressUuid;

    /**
     * 建立连接调用的方法
     * @param session
     * @param progressUuid
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("uuid") String progressUuid) {
        this.session = session;
        this.progressUuid = progressUuid;
        if (webSocketMap.containsKey(progressUuid)) {
            webSocketMap.remove(progressUuid);
            webSocketMap.put(progressUuid, this);
        } else {
            webSocketMap.put(progressUuid, this);
            addOnlineCount();
        }
        logger.info("WxWebSocketServer =====>>>>>> 用户发起授权了，当前等待授权人数：" + getOnlineCount());
    }

    /**
     * 关闭连接时调用的方法
     */
    @OnClose
    public void onClose() {
        logger.info("WxWebSocketServer =====>>>>>> 连接关闭了");
        if (webSocketMap.containsKey(this.progressUuid)) {
            webSocketMap.remove(this.progressUuid);
            subOnlineCount();
        }
        logger.info("当前授权状态已退出：" + progressUuid + " ，当前未完成授权：" + getOnlineCount());
    }

    /**
     * 出现错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("WxWebSocketServer =====>>>>>> 出现错误了，出错用户：" + this.progressUuid + "，出错原因：" + error.getMessage());
    }

    /**
     * 接收客户端发送过来的消息
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        logger.info("WxWebSocketServer =====>>>>>> 客户端发送消息过来了，消息内容："+ message);
    }

    /**
     * 实现服务器主动推送消息到客户端
     * @param message
     */
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
        }
    }

    /**
     * 自定义推送消息的方法，方便外部调用
     * @param progressUuid 进度唯一识别码
     */
    public static void send(String progressUuid) {
        if (StringUtils.isBlank(progressUuid) || !webSocketMap.containsKey(progressUuid)) {
            logger.error("当前["+ progressUuid +"]的微信uuid已失效！");
            return;
        }
        JSONObject obj = new JSONObject();
        obj.put("author", true);
        obj.put("message", "");
        logger.info("发送消息：{}", obj);
        webSocketMap.get(progressUuid).sendMessage(obj.toJSONString());
    }


    /**
     * 获取当前在线人数
     * @return
     */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 增加在线人数
     */
    public static synchronized void addOnlineCount() {
        WxWebSocketServer.onlineCount++;
    }

    /**
     * 减少在线人数
     */
    public static synchronized void subOnlineCount() {
        WxWebSocketServer.onlineCount--;
    }




}
